package helperService

import (
	"errors"
	"gitee.com/yangguoliang001/go-gin-vue3/BO"
	"gitee.com/yangguoliang001/go-gin-vue3/QO"
	"gitee.com/yangguoliang001/go-gin-vue3/common"
	"gitee.com/yangguoliang001/go-gin-vue3/pkg/response"
	"gitee.com/yangguoliang001/go-gin-vue3/util/code"
	"gitee.com/yangguoliang001/go-gin-vue3/vo"
	"github.com/gin-gonic/gin"
	"strings"
)

func (h helperService) QueryDbs(c *gin.Context) (dbsRes vo.DbsVO, err error) {
	var dbsList vo.DbsVO
	db := vo.DbData{DbName: common.Get().MySQL.Name}
	dbsList.List = append(dbsList.List, db)
	return dbsList, nil
}

func (h helperService) QueryTables(c *gin.Context, tableReq QO.DbTableReq) (tableRes vo.DbTableVO, err error) {
	var tables []BO.DbTablesBO
	tables, err = h.helperDao.QueryTables(tableReq.DbName)
	if err != nil {
		response.Fail(c, code.MySQLExecError, code.Text(code.MySQLExecError), gin.H{"realErr": err})
		return vo.DbTableVO{}, err
	}
	return vo.DbTableVO{
		List: tables,
	}, err
}

func (h helperService) SearchMysql(c *gin.Context, searchReq QO.SearchMysqlReq) (searchRes vo.SearchMysqlDataVO, err error) {

	sql := strings.ToLower(strings.TrimSpace(searchReq.Sql))
	if sql == "" {
		err = errors.New("sql语句不能为空")
		response.Fail(c, code.MySQLExecError, code.Text(code.MySQLExecError), gin.H{"realErr": err.Error()})
		return vo.SearchMysqlDataVO{}, err
	}
	prefix := string([]byte(sql)[:6])
	if PreFilterList[prefix] {
		err = errors.New("sql语句不能以" + prefix + "开头")
		response.Fail(c, code.MySQLExecError, code.Text(code.MySQLExecError), gin.H{"realErr": err.Error()})
		return vo.SearchMysqlDataVO{}, err
	}
	for _, f := range FilterListKeyword {
		if find := strings.Contains(sql, f); find {

			isWhiteList := false
			for _, w := range WhiteListKeyword {
				if whiteFind := strings.Contains(sql, w); whiteFind {
					isWhiteList = true
					break
				}
			}

			if !isWhiteList {
				err = errors.New("sql语句存在敏感词" + f + "！")
				response.Fail(c, code.MySQLExecError, code.Text(code.MySQLExecError), gin.H{"realErr": err.Error()})
				return vo.SearchMysqlDataVO{}, err
			}

		}
	}

	if strings.ToLower(prefix) == "select" && !strings.Contains(sql, "limit") {
		if strings.HasSuffix(sql, ";") {
			sql = strings.ReplaceAll(sql, ";", " LIMIT 100;")
		} else {
			sql += " LIMIT 100;"
		}
	}

	tableData, err := h.helperDao.QueryTableData(sql)
	if err != nil {
		response.Fail(c, code.MySQLExecError, code.Text(code.MySQLExecError), gin.H{"realErr": err})
		return vo.SearchMysqlDataVO{}, err
	}
	columnsInfo, err := h.helperDao.QueryTableColumns(searchReq)

	if err != nil {
		response.Fail(c, code.MySQLExecError, code.Text(code.MySQLExecError), gin.H{"realErr": err})
		return vo.SearchMysqlDataVO{}, err
	}
	return vo.SearchMysqlDataVO{
		List:     tableData.List,
		Cols:     tableData.Cols,
		ColsInfo: columnsInfo,
	}, nil
}
